﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Calculator
{
    public partial class Form1 : Form
    {
        private Calculator calc;

        public Form1()
        {
            InitializeComponent();
            // set the button tag for the generic on click method
            btnAdd.Tag = CalcOperationType.ADD;
            btnClear.Tag = CalcOperationType.CLEAR;
            btnClearEverything.Tag = CalcOperationType.CLEARALL;
            btnDeci.Tag = CalcOperationType.DECIMAL;
            btnDivide.Tag = CalcOperationType.DIVIDE;
            btnEquals.Tag = CalcOperationType.EQUALS;
            btnMultiply.Tag = CalcOperationType.MULTIPLY;
            btnPosNeg.Tag = CalcOperationType.SIGN;
            btnSubtract.Tag = CalcOperationType.SUBTRACT;

            btn0.Tag = 0;
            btn1.Tag = 1;
            btn2.Tag = 2;
            btn3.Tag = 3;
            btn4.Tag = 4;
            btn5.Tag = 5;
            btn6.Tag = 6;
            btn7.Tag = 7;
            btn8.Tag = 8;
            btn9.Tag = 9;

            calc = new Calculator();
            calc.DisplayUpdatedEvent += new Calculator.DisplayUpdatedHandler(UpdateDisplay);
            txtDisplay.DataBindings.Add("Text", calc, "Display");
        }

        private void NumberButton_Click(object sender, EventArgs e)
        {
            calc.ReceiveNumber((int)(sender as Button).Tag);
        }

        private void OperationButton_Click(object sender, EventArgs e)
        {
            calc.ProcessOperation((CalcOperationType)(sender as Button).Tag);
            if ((CalcOperationType)(sender as Button).Tag == CalcOperationType.EQUALS)
            {
                String[] lines = new String[calc.TapePos];
                Array.Copy(calc.Tape, lines, calc.TapePos);
                txtTape.Lines = lines;
            }

            if ((CalcOperationType)(sender as Button).Tag == CalcOperationType.CLEARALL)
            {
                txtTape.Lines = new String[0];
            }
        }

        private void UpdateDisplay(object sender, EventArgs e)
        {
            txtDisplay.DataBindings.Clear();
            txtDisplay.DataBindings.Add("Text", calc, "Display");
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private int m_currentPrintLine = 0;
        private void ctPrintDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            float yPos = 0f;
            int count = 0;
            float leftMargin = e.MarginBounds.Left;
            float topMargin = e.MarginBounds.Top;
            string line = null;
            float linesPerPage = e.MarginBounds.Height /
                txtTape.Font.GetHeight(e.Graphics);
            //m_current Print Line is a class scope variable of type int.
            while (m_currentPrintLine < txtTape.Lines.Count()
                && count < linesPerPage)
            {
                line = txtTape.Lines[m_currentPrintLine];  //txtTape.Lines is a multi-line text box on the form.
                m_currentPrintLine++;
                yPos = topMargin + count * txtTape.Font.GetHeight(e.Graphics);
                e.Graphics.DrawString(line, txtTape.Font, Brushes.Black,
                    leftMargin, yPos, new StringFormat());
                count++;
            }
            if (m_currentPrintLine < txtTape.Lines.Count())
            {
                e.HasMorePages = true;
            }
        }

        private void printToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_currentPrintLine = 0;
            ctPrintDocument.Print();
        }

        private void printPreviewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_currentPrintLine = 0;
            ctPrintPreviewDialog.ShowDialog();
        }
    }
}
